home *** CD-ROM | disk | FTP | other *** search
- /* ServiceMgr.c
- * Handle the Services menu in Writeswell, Jr.
- * ©1992 Working Software, Inc.
- * This source code is copyrighted. Permission is granted to use the Word Services
- * portion of the Writeswell Jr. source code in your own programs, but you
- * may not distribute the Writeswell Jr. word-processor code as a
- * commercial product. If you modify the code, please do not call it
- * Writeswell Jr. (or Writeswell.) This will ensure that people understand the
- * program and don’t have to deal with a number of different versions with
- * who-knows-what going on in the code.
- *
- * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
- * 19 Apr 92 Mike Crawford
- */
-
- #include <Aliases.h>
- #include <AppleEvents.h>
- #include "TestBed.h"
- #include "TBConstants.h"
- #include "Gripe.h"
- #include "Prefs.h"
- #include "ServiceMgr.h"
- #include "TBGlobals.h"
- #include "ServiceDialog.h"
- #include "OutlineButton.h"
- #include "Key.h"
- #include "InitMenu.h"
-
- pascal void ServiceListProc( DialogPtr theDialog, short item );
- OSErr MakeServiceList( DialogPtr dPtr );
- OSErr FillServiceList( ListHandle lHdl );
- pascal Boolean RemoveDlogProc( DialogPtr theDialog,
- EventRecord *eventPtr,
- short *itemPtr );
- void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl );
- void RemoveSelectedServices( ListHandle lHdl );
-
- void RemoveServices( void )
- {
- DialogPtr servDlg;
- short item;
- short kind;
- Handle h;
- Rect r;
- ListHandle lHdl;
- OSErr err;
- UserItemUPP outlineUPP;
- UserItemUPP serviceListUPP;
-
- // Anywhere we use a dialog we must take extra care that UPP's are
- // set up properly on the PowerPC. Because the user item proc is cast
- // as a handle in SetDItem, there is no way for the compiler to know that
- // we are passing in a pointer to a function rather than a pointer to a
- // routine descriptor. One finds out quickly when running the program - it
- // always crashes when displaying a dialog that has a user item.
-
- servDlg = GetNewDialog( rRemoveDialogID, (Ptr)NULL, (WindowPtr)-1 );
- if ( !servDlg )
- return;
-
- /* Set up a user proc to draw the default outline */
-
- GetDItem( servDlg, kRDDefUser, &kind, &h, &r );
-
- outlineUPP = NewUserItemProc( OutlineButton );
- if ( !outlineUPP )
- return; // STUB should report an error
-
- SetDItem( servDlg, kRDDefUser, kind, (Handle)outlineUPP, &r );
-
- /* Set up the user proc to draw the service list */
- GetDItem( servDlg, kRDListUser, &kind, &h, &r );
-
- serviceListUPP = NewUserItemProc( ServiceListProc );
- if ( !serviceListUPP )
- return; // STUB should report an error
-
- SetDItem( servDlg, kRDListUser, kind, (Handle)serviceListUPP, &r );
-
- err = MakeServiceList( servDlg );
- if ( err ){
- Gripe( "\pMakeServiceList failed" );
- return;
- }
-
- lHdl = (ListHandle)GetWRefCon( servDlg );
-
- err = FillServiceList( lHdl );
- if ( err ){
- Gripe( "\pFillServiceList failed" );
- return;
- }
-
- SetPort( servDlg );
-
- LDoDraw( true, lHdl );
-
- HiliteRemoveButton( servDlg, lHdl );
-
- do {
- ModalDialog( (ModalFilterUPP)RemoveDlogProc, &item );
-
- if ( item == kRDRemove ){
- RemoveSelectedServices( lHdl );
- HiliteRemoveButton( servDlg, lHdl );
- }
-
- } while ( item != kRDDone );
-
- LDispose( lHdl );
-
- #ifdef GENERATINGCFM
- DisposeRoutineDescriptor( outlineUPP );
- DisposeRoutineDescriptor( serviceListUPP );
- #endif
-
- DisposDialog( servDlg );
-
- RebuildServiceMenu();
-
- return;
- }
-
- pascal void ServiceListProc( DialogPtr theDialog, short item )
- {
- Handle itemHdl;
- short itemKind;
- Rect itemRect;
- PenState oldPenState;
- ListHandle lHdl;
-
- /* Get the user item rectangle */
- GetDItem( theDialog, item, &itemKind, &itemHdl, &itemRect );
-
- /* Draw the frame around the list */
- GetPenState( &oldPenState );
- PenNormal();
-
- FrameRect( &itemRect );
-
- SetPenState( &oldPenState );
-
- /* Update the list itself */
-
- lHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
-
- LUpdate( ( (WindowPeek)theDialog )->port.visRgn, lHdl );
-
- return;
- }
-
- OSErr MakeServiceList( DialogPtr dPtr )
- {
- Handle itemHdl;
- short itemKind;
- Rect itemRect;
- Rect listRect;
- Rect dataBounds;
- Point cellSize;
- ListHandle lHdl;
-
- /* Get the rect from the dialog user item.
- * The user item exists in the DITL as a placeholder for us to get a rect
- * from, and also to report hits on.
- */
- GetDItem( dPtr, kRDListUser, &itemKind, &itemHdl, &itemRect );
-
- /* Make room for the scroll bar. This is outside of the rect that is passed to
- * LNew.
- * We use a copy of the rect so we don't change the real one in the dialog
- */
-
- listRect = itemRect; /* Structure Assignment */
- listRect.right -= kListScrollBarWidth;
- InsetRect( &listRect, 1, 1 ); /* 1 pixel inside user item to allow outline */
-
- /* Set up the data bounds for a single column list, with no initial elements */
- SetRect( &dataBounds, 0, 0, 1, 0 );
-
- /* Use the default cell size */
- cellSize.h = 0;
- cellSize.v = 0;
-
- /* make the list */
- lHdl = LNew( &listRect, &dataBounds, cellSize, kListTextProc,
- (WindowPtr) dPtr, false, false, false, true );
-
- if ( !lHdl || !*lHdl ){
- Gripe( "\pLNew failed" );
- return memFullErr;
- }
-
- SetWRefCon( dPtr, (long)lHdl );
-
- /* Get the filenames for the list, and install them */
-
- return noErr;
- }
-
- OSErr FillServiceList( ListHandle lHdl )
- {
- WWJrPrefsHdl prefHdl;
- short i;
- short servNum;
- StringHandle menuStrHdl;
- short curFile;
- short resID;
- Cell newCell;
-
- prefHdl = GetPrefHandle();
- if ( !prefHdl ){
- Gripe( "\pCannot get preferences handle" );
- return resNotFound;
- }
-
- curFile = CurResFile();
- UseResFile( gPrefFileRefNum );
-
- servNum = 0;
-
- newCell.h = 0;
-
- for ( i = 0; i < kMaxServices; i++ ){
- if ( (*prefHdl)->serviceType[ i ] != kNoService ){
-
- resID = kServiceBaseID + i;
-
- menuStrHdl = GetString( resID );
- if ( !menuStrHdl ){
- Gripe( "\pCannot get string resource for service menu" );
- UseResFile( curFile );
- return resNotFound;
- }
-
- newCell.v = servNum++;
-
- LAddRow( 1, 32767, lHdl );
-
- HLock( (Handle) menuStrHdl );
- LSetCell( &( (*menuStrHdl)[1] ), (short)((*menuStrHdl)[0]), newCell, lHdl );
- HUnlock( (Handle) menuStrHdl );
-
- ReleaseResource( (Handle) menuStrHdl );
- }
- }
-
- UseResFile( curFile );
- return noErr;
- }
-
- pascal Boolean RemoveDlogProc( DialogPtr theDialog,
- EventRecord *eventPtr,
- short *itemPtr )
- {
- Handle h;
- short kind;
- Rect listRect;
- Point localPt;
- ListHandle listHdl;
-
- switch( eventPtr->what ){
- case keyDown:
- switch( eventPtr->message & charCodeMask ){
- case enterKey:
- case retKey:
- case escKey:
- *itemPtr = kRDDone; /* Take safe way out. May not like this */
- return true;
- break;
- }
- break;
- case mouseDown:
- /* check if it's in the list. Have to do this in the Proc so we can
- * look at the event record
- */
-
- GetDItem( theDialog, kRDListUser, &kind, &h, &listRect );
-
- localPt = eventPtr->where;
- GlobalToLocal( &localPt );
-
- if ( PtInRect( localPt, &listRect ) ){
-
- /* Work around a bug in the List Manager where if there are several
- * files selected, an unshifted click will not deselect the selected files
- */
-
- listHdl = (ListHandle)GetWRefCon( (WindowPtr)theDialog );
-
- if ( ! (eventPtr->modifiers & shiftKey) &&
- !(eventPtr->modifiers & cmdKey) ){
-
-
- if ( PtInRect( localPt, &((*listHdl)->rView) ) ){
- Cell myCell;
-
- /* LDoDraw( false, listhdl ); */
-
- myCell.h = 0;
- myCell.v = 0;
-
- while ( LGetSelect( true, &myCell, listHdl ) ){
- LSetSelect( false, myCell, listHdl );
- }
-
- /* LDoDraw( true, listHdl ); */
- }
- }
- /* We presently don't care if they double-clicked */
- LClick( localPt, eventPtr->modifiers, listHdl );
- HiliteRemoveButton( theDialog, listHdl );
- }
- break;
- case updateEvt:
- LUpdate( ( (WindowPeek)theDialog )->port.visRgn,
- (ListHandle)GetWRefCon( (WindowPtr)theDialog ) );
- break;
- }
-
- return false;
- }
-
- /* Dim or Hilite Remove button according to whether there is a selection */
-
- void HiliteRemoveButton( DialogPtr dPtr, ListHandle lHdl )
- {
- Handle itemHdl;
- short itemKind;
- Rect itemRect;
- Cell theCell;
-
- GetDItem( dPtr, kRDRemove, &itemKind, &itemHdl, &itemRect );
-
- theCell.h = 0;
- theCell.v = 0;
-
- if ( LGetSelect( true, &theCell, lHdl ) ){
- HiliteControl( (ControlHandle)itemHdl, 0 );
- } else {
- HiliteControl( (ControlHandle)itemHdl, 255 );
- }
-
- return;
- }
-
- void RemoveSelectedServices( ListHandle lHdl )
- {
- WWJrPrefsHdl prefHdl;
- short index;
- short servCount;
- short curFile;
- short resID;
- short iconResID;
- Cell nextCell;
- Handle menuStrHdl;
- Handle aliasHdl;
- Handle iconHdl;
- short itemNo;
-
- prefHdl = GetPrefHandle();
- if ( !prefHdl ){
- Gripe( "\pCannot get preferences handle" );
- return;
- }
-
- curFile = CurResFile();
- UseResFile( gPrefFileRefNum );
-
- nextCell.h = 0;
- nextCell.v = 0;
-
-
- while ( LGetSelect( true, &nextCell, lHdl ) ){
-
- itemNo = nextCell.v + 1;
-
- /* We need to unselect the cell we just got so it won't be gotten repeatedly
- * at the end
- */
-
- LSetSelect( false, nextCell, lHdl );
-
- index = 0;
- servCount = 0;
-
- do {
-
- if ( (*prefHdl)->serviceType[ index++ ] != kNoService )
- servCount++;
-
- } while ( servCount < itemNo );
-
- index--;
-
- (*prefHdl)->serviceType[ index ] = kNoService;
-
- resID = kServiceBaseID + index;
-
- /* Remove the resource */
-
- menuStrHdl = GetResource( 'STR ', resID );
-
- if ( !menuStrHdl ){
- Gripe( "\pFailed to get menu string in RemoveSelectedServices" );
- UseResFile( curFile );
- return;
- }
-
- RmveResource( menuStrHdl );
-
- /* 1.1.1 MDC Fix memory leak */
-
- DisposHandle( menuStrHdl );
-
- aliasHdl = GetResource( rAliasType, resID );
-
- if ( !aliasHdl ){
- Gripe( "\pFailed to get alias resource in RemoveSelectedServices" );
- UseResFile( curFile );
- return;
- }
-
- RmveResource( aliasHdl );
-
- /* 1.1.1 MDC Fix memory leak */
-
- DisposHandle( aliasHdl );
-
- /* Remove the icon */
-
- iconResID = kMenuIconBaseID + index;
-
- iconHdl = GetResource( 'SICN', iconResID );
-
- /* It is permissible for there to be no icon resource */
-
- if ( iconHdl ){
- RmveResource( iconHdl );
-
- /* 1.1.1 MDC Fix memory leak */
-
- DisposHandle( iconHdl );
-
- }
-
- LDelRow( 1, nextCell.v, lHdl ); /* Take item out of list */
- }
-
- ChangedResource( (Handle) prefHdl );
- WriteResource( (Handle) prefHdl );
-
- UseResFile( curFile );
- return;
- }
-